fn main() {
    // 捕获上下文
    // let x = 4;

    // 闭包可以访问定义它的作用域内的变量，而普通函数不行
    // 会产生内存开销

    /* 闭包从所在环境捕获值的方式
     *  - 取得所有权：FnOnce
     *    会消耗捕获的变量，将所有权移动到比保重，所以只能使用一次
     *  - 可变借用：FnMut
     *  - 不可变借用：Fn
     *
     * 创建闭包时，通过闭包对环境值的使用，Rust推断出具体使用哪个trait
     *  - *所有的闭包都实现了FnOnce
     *  - *没有移动捕获变量的实现了FnMut
     *  - *无需可变访问捕获变量的闭包实现了Fn
     *  - ** 所有实现了Fn的闭包都实现了FnMut,所有实现了FnMut的闭包，都实现了FnOnce
     */
    // let equal_to_x = |z| z==x;

    // 使用函数 不能捕获x
    // fn equal_to_x(z:i32)->bool {
    //     z==x //can't capture dynamic environment in a fn item
    // }

    // print!("{}",x); // 此时还是可以使用x
    // assert!(equal_to_x(4));

    // move 关键字
    /*
     * 在参数列表前使用move关键字，可以强制闭包取得她所使用的环境值的所有权
     *  - 当将闭包传递给新线程以移动数据使其归新线程所有时，此技术最为有用
     */
    let x = 4;
    let equal_to_x = move |z| z == x;
    let r = equal_to_x(4);

    println!("{}", r);
    println!("{}", x);

  
}
